﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using TaskManager.ViewModels;
using TaskManager.Data;
using TaskManager.Extensions;
using System.Web.Script.Serialization;

using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.Configuration;

namespace TaskManager.Controllers
{
    public class HomeController : Controller
    {
        /// <summary>
        /// Display the Index view.
        /// </summary>
        public ActionResult Index()
        {
            return View();
        }

        /// <summary>
        /// Display the Navigation partial view.
        /// </summary>
        public ActionResult Navigation()
        {
            return View("_Navigation", new Navigation());
        }

        /// <summary>
        /// Display the Sprint partial view.
        /// </summary>
        /// <param name="id">Id of the Sprint to be displayed.</param>
        public ActionResult Sprint(int id)
        {
            Sprint sprint = null;

            using (IUnityContainer container = new UnityContainer())
            {
                container.LoadConfiguration();
                ISprintRepository sprintRepository = container.Resolve<ISprintRepository>();
                sprint = sprintRepository.GetSprints().Where(s => s.SprintId == id).First();
            }
            return View("_Sprint", sprint);
        }

        /// <summary>
        /// Display the Developer parital view.
        /// </summary>
        /// <param name="id">Id of the Developer to be displayed.</param>
        public ActionResult Developer(int id)
        {
            Developer person = null;

            using (IUnityContainer container = new UnityContainer())
            {
                container.LoadConfiguration();
                ISprintRepository sprintRepository = container.Resolve<ISprintRepository>();
                person = sprintRepository.GetDevelopers().Where(d => d.DeveloperId == id).First();
            }
            return View("_Developer", person);
        }

        #region Sprints

        /// <summary>
        /// Get a Sprint.
        /// </summary>
        /// <param name="id">Id of the Sprint to retrieve.</param>
        public JsonResult GetSprint(int id)
        {
            Sprint sprint = null;

            using (IUnityContainer container = new UnityContainer())
            {
                container.LoadConfiguration();
                ISprintRepository sprintRepository = container.Resolve<ISprintRepository>();
                sprint = sprintRepository.GetSprints().Where(s => s.SprintId == id).First();
            }
            return Json(
                new {
                    SprintId = sprint.SprintId,
                    StartDate = sprint.StartDate,
                    EndDate = sprint.EndDate
                }, JsonRequestBehavior.AllowGet
            );
        }

        /// <summary>
        /// Get the Tasks assigned to a Sprint.
        /// </summary>
        /// <param name="id">Id of the Sprint.</param>
        public JsonResult GetSprintTasks(int id)
        {
            Sprint sprint = null;

            using (IUnityContainer container = new UnityContainer())
            {
                container.LoadConfiguration();
                ISprintRepository sprintRepository = container.Resolve<ISprintRepository>();
                sprint = sprintRepository.GetSprints().Where(s => s.SprintId == id).First();
            }
            return Json(sprint.GetTasks().Select(t => new
                {
                    TaskId = t.TaskId,
                    SprintId = t.SprintId,
                    TypeOfTask = t.TypeOfTask,
                    EstimatedHours = t.EstimatedHours,
                    Description = t.Description,
                    AssignedToId = t.AssignedToId,
                    CompletedDate = t.CompletedDate
                }), JsonRequestBehavior.AllowGet
            );
        }

        /// <summary>
        /// Update a Sprint.
        /// </summary>
        /// <param name="sprint">Sprint to be updated.</param>
        [AcceptVerbs(HttpVerbs.Post)]
        public JsonResult UpdateSprint(Sprint sprint)
        {
            string message = string.Empty;

            using (IUnityContainer container = new UnityContainer())
            {
                container.LoadConfiguration();
                ISprintRepository sprintRepository = container.Resolve<ISprintRepository>();
                message = sprintRepository.SaveSprint(sprint);
            }
            return Json(new { message = message }, JsonRequestBehavior.AllowGet);
        }

        #endregion Sprints

        #region Tasks

        /// <summary>
        /// Save a list of Tasks.
        /// </summary>
        /// <param name="tasks">Tasks to be saved.</param>
        /// <param name="delete">Indicates the list of tasks are to be deleted.</param>
        [AcceptVerbs(HttpVerbs.Post)]
        [JsonParameter(Input="models", Output="tasks", DataType=typeof(IList<Task>))]
        public JsonResult SaveTasks(IList<Task> tasks, bool delete = false)
        {
            using (IUnityContainer container = new UnityContainer())
            {
                foreach (Task task in tasks)
                {
                    container.LoadConfiguration();
                    ISprintRepository sprintRepository = container.Resolve<ISprintRepository>();
                    sprintRepository.SaveTask(task, delete);
                }
            }
            return Json(new { result = "complete" });
        }

        #endregion Tasks

        #region Developers

        /// <summary>
        /// Get all the Developers.
        /// </summary>
        public JsonResult GetDevelopers()
        {
            IList<Developer> developers = null;

            using (IUnityContainer container = new UnityContainer())
            {
                container.LoadConfiguration();
                ISprintRepository sprintRepository = container.Resolve<ISprintRepository>();
                developers = sprintRepository.GetDevelopers();
            }
            return Json(developers.Select(d => new
                {
                    DeveloperId = d.DeveloperId,
                    FirstName = d.FirstName,
                    LastName = d.LastName,
                    Name = string.Format("{0} {1}", d.FirstName, d.LastName),
                    Title = d.Title
                }), JsonRequestBehavior.AllowGet);
        }

        /// <summary>
        /// Get a Developer.
        /// </summary>
        /// <param name="id">Id of the Developer to retrieve.</param>
        public JsonResult GetDeveloper(int id)
        {
            Developer developer = null;

            using (IUnityContainer container = new UnityContainer())
            {
                container.LoadConfiguration();
                ISprintRepository sprintRepository = container.Resolve<ISprintRepository>();
                developer = sprintRepository.GetDevelopers().Where(d => d.DeveloperId == id).First();
            }

            return Json(developer, JsonRequestBehavior.AllowGet);
        }

        /// <summary>
        /// Get the Tasks assigned to a Developer.
        /// </summary>
        /// <param name="id">Id of the Developer.</param>
        public JsonResult GetDeveloperTasks(int id)
        {
            Developer developer = null;

            using (IUnityContainer container = new UnityContainer())
            {
                container.LoadConfiguration();
                ISprintRepository sprintRepository = container.Resolve<ISprintRepository>();
                developer = sprintRepository.GetDevelopers().Where(d => d.DeveloperId == id).First();
            }
            return Json(developer.GetTasks().Select(t => new
                {
                    TaskId = t.TaskId,
                    SprintId = t.SprintId,
                    TypeOfTask = t.TypeOfTask,
                    EstimatedHours = t.EstimatedHours,
                    Description = t.Description,
                    AssignedToId = t.AssignedToId,
                    CompletedDate = t.CompletedDate
                }), JsonRequestBehavior.AllowGet
            );
        }

        /// <summary>
        /// Update a Developer.
        /// </summary>
        /// <param name="developer">Developer to be updated.</param>
        [AcceptVerbs(HttpVerbs.Post)]
        public void UpdateDeveloper(Developer developer)
        {
            using (IUnityContainer container = new UnityContainer())
            {
                container.LoadConfiguration();
                ISprintRepository sprintRepository = container.Resolve<ISprintRepository>();
                sprintRepository.SaveDeveloper(developer);
            }
        }

        #endregion Developers
    }
}